package cn.itcast.web.shiro;

import cn.itcast.domain.system.Module;
import cn.itcast.domain.system.User;
import cn.itcast.service.system.ModuleService;
import cn.itcast.service.system.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

public class AuthRealm extends AuthorizingRealm {


    @Autowired
    private UserService userService;

    @Autowired
    private ModuleService moduleService;

    //当subject调用login方法，其实本质上是调用doGetAuthenticationInfo()方法
    //并且doGetAuthenticationInfo方法的token就是login方法传递过来的token。
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //1. 先从token取出用户输入邮箱与密码
        UsernamePasswordToken usernamePasswordToken = (UsernamePasswordToken) token;
        String email = usernamePasswordToken.getUsername();

        //2. 根据邮箱去查找用户，如果查找出来的用户为null，我们直接返回null，那么subject对象就会收到UnknownAccountException异常
        User user = userService.findByEmail(email);
        if(user==null){
            //我们直接返回null，那么subject对象就会收到UnknownAccountException异常
            return null;
        }

        //3. 对比密码,对比密码的这个过程shiro要自己去完成，你只需要把数据库的密码交给shiro即可。
        /*
          参数一：principal  登录成功后返回的对象
          参数二：credentials  当前用户的数据库密码(这里注意不是用户输入密码)
          参数三：realmName   不需要管理
         */
        AuthenticationInfo authenticationInfo = new SimpleAuthenticationInfo(user,user.getPassword(),"");
        return authenticationInfo;
    }





    /*
        用户登录成功之后就会调用该方法给用户去授权
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {

        System.out.println("调用了AuthorizationInfo");
        //1. 得到登陆成功用户对象
        User user = (User) principals.getPrimaryPrincipal();
        //2. 得到用户拥有的权限
        List<Module> moduleList = moduleService.findModuleByUser(user);

        //3. 把用户权限的标记添加到AuthorizationInfo(集合)
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        for (Module module : moduleList) {
            simpleAuthorizationInfo.addStringPermission(module.getName()); //权限标记一般我们使用菜单名字
        }
        return simpleAuthorizationInfo;
    }



}